package com.yy.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yy.dao.GptDoctorEvaluationMapper;
import com.yy.domain.GptPatientEvaluationDO;
import com.yy.dao.GptPatientEvaluationMapper;
import com.yy.domain.GptPatientValueEvaluationDO;
import com.yy.dto.GptDoctorEvaluationDTO;
import com.yy.dto.GptPatientEvaluationDTO;
import com.yy.service.GptPatientEvaluationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yy.service.GptPatientValueEvaluationService;
import com.yy.utils.ConvertUtils;
import com.yy.vo.PatientEvaluationVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 姚欣宏
 * @since 2023-11-14
 */
@Service
public class GptPatientEvaluationServiceImpl extends ServiceImpl<GptPatientEvaluationMapper, GptPatientEvaluationDO> implements GptPatientEvaluationService {

    @Autowired
    GptDoctorEvaluationMapper gptDoctorEvaluationMapper;

    @Autowired
    GptPatientValueEvaluationService gptPatientValueEvaluationService;

    @Override
    public Integer insertEvaluate(PatientEvaluationVO patientEvaluationVO) {
        GptPatientValueEvaluationDO gptPatientValueEvaluationDO = ConvertUtils.beanCopy(patientEvaluationVO, GptPatientValueEvaluationDO.class);
        gptPatientValueEvaluationDO.setCreateDate(new Date());
        gptPatientValueEvaluationService.save(gptPatientValueEvaluationDO);

        Integer id = gptPatientValueEvaluationDO.getId();
        Integer gptSort = patientEvaluationVO.getGptSort();
        Integer gptCtId = patientEvaluationVO.getGptCtId();

        QueryWrapper<GptPatientEvaluationDO> wrapper = new QueryWrapper<>();
        wrapper.eq("gpt_ct_id", gptCtId);
        GptPatientEvaluationDO gptPatientEvaluationDO = getOne(wrapper);

        if (ObjectUtil.isNull(gptPatientEvaluationDO)) {
            gptPatientEvaluationDO = createNewGptPatientEvaluation(gptCtId, id, gptSort);
            save(gptPatientEvaluationDO);
        } else {
            updateGptPatientEvaluation(gptPatientEvaluationDO, id, gptSort);
            updateById(gptPatientEvaluationDO);
        }

        return gptPatientEvaluationDO.getId();
    }

    private GptPatientEvaluationDO createNewGptPatientEvaluation(Integer gptCtId, Integer id, Integer gptSort) {
        GptPatientEvaluationDO newGptPatientEvaluation = new GptPatientEvaluationDO();
        newGptPatientEvaluation.setGptCtId(gptCtId);
        newGptPatientEvaluation.setCreateDate(new Date());

        setGptSortValue(newGptPatientEvaluation, id, gptSort);

        return newGptPatientEvaluation;
    }

    private void updateGptPatientEvaluation(GptPatientEvaluationDO existingGptPatientEvaluation, Integer id, Integer gptSort) {
        setGptSortValue(existingGptPatientEvaluation, id, gptSort);
    }

    private void setGptSortValue(GptPatientEvaluationDO gptPatientEvaluationDO, Integer id, Integer gptSort) {
        switch (gptSort) {
            case 0:
                gptPatientEvaluationDO.setGptValueId(id);
                break;
            case 1:
                gptPatientEvaluationDO.setGptValue1Id(id);
                break;
            case 2:
                gptPatientEvaluationDO.setGptValue2Id(id);
                break;
            default:
                throw new IllegalArgumentException("Invalid gptSort value: " + gptSort);
        }
    }


    @Override
    public GptPatientEvaluationDTO getGptPatient() {
        GptPatientEvaluationDTO gptPatientEvaluationDTO = new GptPatientEvaluationDTO();
        List<GptDoctorEvaluationDTO> gptDoctorEvaluationDTOList = gptDoctorEvaluationMapper.selectDoctorEvaluations();
        List<GptPatientEvaluationDO> gptPatientEvaluationDOS = list();
        if (CollUtil.isEmpty(gptPatientEvaluationDOS)) {
            Collections.shuffle(gptDoctorEvaluationDTOList);
            GptDoctorEvaluationDTO gptDoctorEvaluationDTO = gptDoctorEvaluationDTOList.stream()
                    .findAny()
                    .orElseThrow(() -> new NoSuchElementException("No evaluations available"));
            gptPatientEvaluationDTO.setId(gptDoctorEvaluationDTO.getId());
            gptPatientEvaluationDTO.setDesValue(gptDoctorEvaluationDTO.getDesValue());
            setGptPatientValues(gptPatientEvaluationDTO, gptDoctorEvaluationDTO);
        } else {
            Map<Integer, GptPatientEvaluationDO> doMap = gptPatientEvaluationDOS.stream()
                    .collect(Collectors.toMap(GptPatientEvaluationDO::getGptCtId, Function.identity()));
            Iterator<GptDoctorEvaluationDTO> iterator = gptDoctorEvaluationDTOList.iterator();
            while (iterator.hasNext()) {
                GptDoctorEvaluationDTO doctorEvaluation = iterator.next();
                GptPatientEvaluationDO matchedDO = doMap.get(doctorEvaluation.getId().intValue());
                gptPatientEvaluationDTO.setId(doctorEvaluation.getId());
                gptPatientEvaluationDTO.setDesValue(doctorEvaluation.getDesValue());
                if (matchedDO == null) {
                    setGptPatientValues(gptPatientEvaluationDTO, doctorEvaluation);
                    break;
                } else {
                    if (ObjectUtil.isNull(matchedDO.getGptValue2Id())) {
                        gptPatientEvaluationDTO.setGptValueId(2);
                        gptPatientEvaluationDTO.setGptValue(doctorEvaluation.getGptValue2());
                        break;
                    }
                    iterator.remove();
                }
            }
        }
        return gptPatientEvaluationDTO;
    }

    private void setGptPatientValues(GptPatientEvaluationDTO gptPatientEvaluationDTO, GptDoctorEvaluationDTO doctorEvaluation) {
        gptPatientEvaluationDTO.setGptValueId(2);
        gptPatientEvaluationDTO.setGptValue(doctorEvaluation.getGptValue2());
    }

}
